﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PetShop
{
    struct fish
    {
        int weight;
        int size;
        int type;
    }
    interface ICatchMice
    {
        void CatchMice();
    }
    interface IClimbTree
    {
        void ClimbTree();
    }
    abstract public class Pet
    {

        public Pet(string name)
        {
            _name = name;
            _age = 0;           
        }
        protected string _name;
        protected int _age;
        public void PrintName()
        {
            Console.WriteLine("Pet's name is "+_name);
        }
        public void ShowAge()
        {
            Console.WriteLine(_name + "'s Age =" + _age);
        }
        abstract public void Speak();
        virtual public void Move()
        {

        }
        public static void TestS()
        {
            Console.WriteLine("abc");
        }
        public static Pet operator ++(Pet pet)
        {
            ++pet._age;
            return pet;
        }
    }
    public class Dog : Pet
    {
        static int Num;
        public delegate void Handler();
        public static event Handler NewDog;
        static Dog()
        {
            Num = 0;
        }
        public Dog(string name)
            :base(name)
        {
            ++Num;
            if (NewDog != null)
            {
                NewDog();
            }
        }
        new public void PrintName()
        {
            Console.WriteLine("宠物的名字是 " + _name);
        }
        sealed override public void Speak()
        {
            Console.WriteLine(_name + " is speaking " + "wow");
        }
        override public void Move()
        {

        }
        static public void ShowNum()
        {
            Console.WriteLine("Dog's number = " + Num);
        }
        public void IsHappy<T>(T target) where T : Pet
        {
            Console.WriteLine("Happy:");
            target.PrintName();
            
        }
        public static implicit operator Cat(Dog dog)
        {
            return new Cat(dog._name);
        }
        public void WagTail()
        {
            Console.WriteLine(_name + " wag Tail");
        }
    }

    public class Cat : Pet, ICatchMice, IClimbTree
    {
        public Cat(string name)
            :base(name)
        {
        }
        override public void Speak()
        {
            Console.WriteLine(_name + " is speaking " + "miao");
        }
        public void CatchMice()
        {
            Console.WriteLine("Catch mice");
        }
        public void ClimbTree()
        {
            Console.WriteLine("climb tree");
        }
        public static explicit operator Dog(Cat cat)
        {
            return new Dog(cat._name);
        }
        public void InnocentLook()
        {
            Console.WriteLine(_name + " innocent Look");
        }
    }
    public class Cage<T>
    {
        T[] array;
        readonly int Size;
        int num;
        public Cage(int n)
        {
            Size = n;
            num = 0;
            array = new T[Size];

        }
        public void Putin(T pet)
        {
            if (num < Size)
            {
                array[num++] = pet;
            }
            else
            {
                Console.WriteLine("cage is full");
            }
        }
        public T TakeOut()
        {
            if (num > 0)
            {
                return array[--num];
            }
            else
            {
                Console.WriteLine("cage is empty");
                return default(T);
            }
        }

    }
  
    public abstract class DogCmd
    {
        public abstract string GetCmd();
    }
    public class SitDogCmd : DogCmd
    {
        public override string GetCmd()
        {
            return "sit";
        }
    }
    public class SpeakDogCmd : DogCmd
    {
        public override string GetCmd()
        {
            return "wow";
        }
    }

    public interface IDogLearn<C> where C : DogCmd
    {
        void Act(C cmd);
    } 
    public class Labrador : Dog, IDogLearn<SitDogCmd>, IDogLearn<SpeakDogCmd>
    {
        public Labrador(string name)
            : base(name)
        {

        }
        //override public void Speak()
        //{
        //    Console.WriteLine("hhhhh");
        //}

        public void Act(SitDogCmd cmd)
        {
            Console.WriteLine(cmd.GetCmd());
        }
        public void Act(SpeakDogCmd cmd)
        {
            Console.WriteLine(cmd.GetCmd());
        }

    }

    static class PetGuide
    {
        static public void HowToFeedDog(this Dog dog)
        {
            Console.WriteLine("Play a vedio about how to feed a dog");
        }
    }

    class Person
    {
    }
    class Client
    {
        public void WantADog()
        {
            Console.WriteLine("Great,I want to see the new dog");
        }
    }
    class Program
    {
        delegate void ActCute();

        static void Main(string[] args)
        {
            Client c1 = new Client();
            Client c2 = new Client();
            Dog.NewDog += c1.WantADog;
            Dog.NewDog += c2.WantADog;

            Dog dog = new Dog("Q");


            //ActCute del = null;
            //Dog dog = new Dog("A");
            //Cat cat = new Cat("B");
            //del = dog.WagTail;
            //del += cat.InnocentLook;
            //del += () =>
            //    {
            //        Console.WriteLine("do nothing");
            //    };
            //del();
            //Queue<Pet> quene = new Queue<Pet>();
            //quene.Enqueue(new Dog("A"));
            //quene.Enqueue(new Dog("B"));
            //quene.Enqueue(new Dog("C"));
            //Pet pet = null;
            //pet = quene.Dequeue();
            //pet.PrintName();
            //pet = quene.Dequeue();
            //pet.PrintName();
            //pet = quene.Dequeue();
            //pet.PrintName();
             
            //Stack<Pet> stack = new Stack<Pet>();
            //stack.Push(new Dog("A"));
            //stack.Push(new Dog("B"));

            //stack.Peek().PrintName();
            //stack.Pop();
            //stack.Peek().PrintName();

            //Dictionary<string, Dog> dic = new Dictionary<string, Dog>();
            //dic.Add("A", new Dog("A"));
            //dic.Add("B", new Dog("B"));
            //dic.Add("C", new Dog("C"));
            //dic["A"].PrintName();

            //List<Dog> list = new List<Dog>();
            //list.Add(new Dog("A"));
            //list.Add(new Dog("B"));
            //list.Add(new Dog("C"));
            //list.RemoveAt(1);
            //for (int i = 0; i < list.Count; i++)
            //{
            //    list[i].PrintName();
            //}           
            
            //Labrador dog = new Labrador("A");
            //dog.Act(new SitDogCmd());
            //dog.Act(new SpeakDogCmd());
            
            //var dog = new Dog("A");

            //dog.IsHappy<Cat>(new Cat("Tom"));

            //Pet[] pets = new Pet[] { new Dog("Jack"), new Cat("Tom"), new Dog("Cherry") };

            //for (int i = 0; i < pets.Length; i++)
            //{
            //    pets[i].Speak();
            //}
            //Cat c = new Cat("Tom2");
            //IClimbTree climb = (IClimbTree)c;
            //c.ClimbTree();
            //climb.ClimbTree();
            //ICatchMice catchM = (ICatchMice)c;
            //c.CatchMice();
            //catchM.CatchMice();

            //Dog.ShowNum();
            ////Math.Abs(-1);

            //Dog dog = new Dog("Tommy");
            //dog.HowToFeedDog();

            //{
            //    int i = 3;
            //    object oi = i;
            //    Console.WriteLine("i=" + i + " oi=" + oi.ToString());
            //    oi = 10;
            //    i = 7;
            //    Console.WriteLine("i=" + i + " oi=" + oi.ToString());

            //    int j = (int)oi;
            //    Console.WriteLine("j=" + j);
            //}
            //dog = new Dog("Jack");
            //dog.Speak();
            //Cat cat = dog;
            //cat.Speak();
            //cat.PrintName();
            //Dog dog2 = (Dog)cat;
            //dog2.Speak();          

            //Pet[] pets = new Pet[] { new Dog("Jcak"), new Cat("Tom"), new Dog("Cherry") };
            //for (int i = 0; i < pets.Length; i++)
            //{
            //    ++pets[i];
            //    pets[i].ShowAge();
            //}
            //var dogCage = new Cage<Cat>(1);
            //dogCage.Putin(new Cat("A"));
            //dogCage.Putin(new Cat("B"));
            //var cat = dogCage.TakeOut();
            //cat.PrintName();
        }
    }
}
